/*
 * Copyright (c) 2021 The red-star Project
 *
 * Licensed under the Apache License, version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.inyourcode.example.cluster.client;
import com.alibaba.fastjson.JSONObject;
import com.inyourcode.core.transport.api.payload.BytesHolder;
import com.inyourcode.core.transport.session.BasicTcpConnector;
import com.inyourcode.core.transport.session.IllegalHandlerException;
import com.inyourcode.core.transport.session.MessageCoderFactory;
import com.inyourcode.core.transport.session.RequestContext;
import com.inyourcode.core.transport.session.SessionHandlerMapping;
import com.inyourcode.core.transport.session.api.IMessageCoder;
import com.inyourcode.example.service.IErrorCode;
import com.inyourcode.example.service.InvokeId;
import com.inyourcode.example.service.data.C2LLogin;
import com.inyourcode.example.service.data.C2Logout;
import com.inyourcode.example.service.handler.LoginHandler;
import com.inyourcode.example.service.login.http.HttpLoginResult;
import com.inyourcode.core.serialization.api.SerializerType;
import com.inyourcode.core.transport.api.JConnection;
import com.inyourcode.core.transport.api.UnresolvedAddress;
import com.inyourcode.core.transport.http.HttpClientUtil;
import io.netty.channel.Channel;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author JackLei
 */
public class ClientApp1 {
    private static final Logger LOGGER = LoggerFactory.getLogger(ClientApp1.class);
    private static volatile Channel channel;
    private static AtomicInteger traceIdGen = new AtomicInteger();

    public static void main(String[] args) throws IllegalHandlerException {
        AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext();
        configApplicationContext.register(ClientNode.class);
        configApplicationContext.refresh();
        SessionHandlerMapping.mappingHandler(Arrays.asList(new LoginHandler()));

        Thread thread = new Thread("T#CMD") {
            @Override
            public void run() {
                BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
                byte serializeType = SerializerType.MSGPACK.value();
                IMessageCoder messageCoder = MessageCoderFactory.getMessageCoder(serializeType);

                while (true) {
                    String msg = null;
                    try {
                        msg = console.readLine();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    if (msg == null) {
                        break;
                    }

                    try {
                        String[] params = msg.split("#");
                        String cmd = params[0];
                        String param = "";
                        if (params.length == 2) {
                            param = params[1];
                        }

                        if ("httplogin".equals(cmd.toLowerCase())) {
                            String openId = param;
                            HttpClientUtil httpClientUtil = configApplicationContext.getBean("httpClient", HttpClientUtil.class);
                            RequestBuilder requestBuilder = RequestBuilder.get("http://127.0.0.1:8051/login").addParameter("openId", openId);

                            try {
                                CloseableHttpResponse response = httpClientUtil.getClient().execute(requestBuilder.build());
                                String content = EntityUtils.toString(response.getEntity(), "UTF-8");
                                HttpLoginResult httpLoginResult = JSONObject.parseObject(content, HttpLoginResult.class);

                                LOGGER.info("recive login server message, data:{}", content);
                                if (httpLoginResult.code == IErrorCode.SUCCESS) {
                                    BasicTcpConnector tcpConnector = configApplicationContext.getBean("tcpConnector", BasicTcpConnector.class);

                                    JConnection jConnection = tcpConnector.connect(new UnresolvedAddress(httpLoginResult.host, httpLoginResult.port), true);
                                    jConnection.setReconnect(false);

                                    jConnection.operationComplete((ch) -> {
                                        channel = ch;

                                        C2LLogin login = new C2LLogin();
                                        login.openId = openId;
                                        login.token = httpLoginResult.token;
                                        login.platId = 1;
                                        login.platType = 1;

                                        RequestContext requestContext = new RequestContext(InvokeId.C2L_Login, traceIdGen.incrementAndGet(), login, serializeType, System.currentTimeMillis());
                                        BytesHolder jRequestPayload = messageCoder.encode(requestContext);

                                        ch.writeAndFlush(jRequestPayload);
                                    });
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        } else if ("logout".equals(cmd)) {
                            C2Logout login = new C2Logout();

                            RequestContext requestContext = new RequestContext(InvokeId.C2L_Logout, traceIdGen.incrementAndGet(), login, serializeType, System.currentTimeMillis());
                            BytesHolder jRequestPayload = messageCoder.encode(requestContext);

                            channel.writeAndFlush(jRequestPayload);
                        } else {
                            //do nothing
                        }
                    }catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        };

        thread.start();
    }
}
